package com.zjj.bams.dao;

import com.zjj.bams.entity.Account;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
 * @author zhoujunjie
 * @desc TODO
 * @date
 */
/**
 * 任务单08需求：
 * 1.id.txt
 *      存储路径：存储在当前项目下
 *      存储内容：下一个账户ID
 *      写PrintWriter  读BufferedReader
 * 2.第一种方案：
 *      存储路径：存储在当前项目下 account.txt
 *      存储内容：将List<Account>集合存储至文件
 *      写ObjectOutputStream序列化  读ObjectInputStream反序列化
 *   第二种方案： 选择这种
 *      存储路径：存储在当前项目下 account/862150212025040001.txt
 *      存储内容：将Account账户信息存储至文件
 *      写ObjectOutputStream序列化  读ObjectInputStream反序列化
 */
public class FileDao implements IDao<Account, List<Account>> {

    //存储下一个ID
    File idFile = new File("id.txt");
    //存储所有Account账户信息至文件夹中 account/862150212025040001.txt
    File accFile = new File("account");

    public FileDao(){
        //若id.txt不存在，则先创建文件
        if(!idFile.exists()){
            try {
                idFile.createNewFile();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //若account文件夹不存在，则先创建文件夹
        if(!accFile.exists()){
            accFile.mkdirs();
        }
    }

    //-------------------------id.txt文件 存取ID账户-------------------------
    //读数据：从id.txt文件中读取ID  BufferedReader
    @Override
    public Long getId() {
        try (
            BufferedReader br = new BufferedReader(new FileReader(idFile))
        ){
            String s = br.readLine();
            //第一次读取文本，赋值初始值
            if(s==null || s.equals("")){
                s = "100000000000000000";
            }
            Long id = Long.valueOf(s);
            return id;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //写数据：从内存中写入ID至磁盘文件id.txt文件  PrintWriter
    @Override
    public void setId(Long id) {
        try (
            PrintWriter pw = new PrintWriter(idFile);
        ){
            pw.println(id);
            pw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    //-------------------------id.txt文件 存取ID账户-------------------------


    //-----------------account/862150212025040001.txt文件 存取账户Account信息-----------------
    //针对于Account账户信息  写  序列化   ObjectOutputStream
    public void writeAcc(Account acc){
        try (
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(accFile , acc.getId()+".txt")))
        ){
            oos.writeObject(acc);
            oos.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //针对于Account账户信息  读  反序列化 ObjectInputStream
    public Account readAcc(Long id){
        try (
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(accFile , id+".txt")))
        ){
            Account acc = (Account)ois.readObject();
            return acc;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    //插入 写
    @Override
    public boolean insert(Account account) {
        writeAcc(account);
        return true;
    }

    //查询 读
    @Override
    public Account selectOne(Long id, String password) {
        Account acc = this.selectOne(id);
        if(acc!=null && acc.getPassword().equals(password)){
            return acc;
        }
        return null;
    }

    //查询 读
    @Override
    public Account selectOne(Long id) {
        Account acc = readAcc(id);
        if(acc!=null && acc.getId().equals(id)){
            return acc;
        }
        return null;
    }

    @Override
    public List<Account> selectAll() {
        List<Account> accs = new ArrayList<>();
        //获取文件夹下的所有文件
        String[] strs = accFile.list();
        //862150212025040001.txt  -> 862150212025040001 -> readAcc(id) -> Account
        Stream.of(strs).forEach(str ->{
            String id = str.substring(0, str.length()-4);
            //读数据
            Account acc = readAcc(Long.parseLong(id));
            accs.add(acc);
        });
        return accs;
    }

    //更新 写
    @Override
    public boolean update(Account account) {
        writeAcc(account);
        return true;
    }
    //-----------------account/862150212025040001.txt文件 存取账户Account信息-----------------
}
